package org.miyuki4j.cfgtool;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.miyuki4j.cfgtool.exception.DataVerifyException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

@SuppressWarnings({"rawtypes", "unchecked"})
@Getter
@Slf4j
public class TableImportData implements Iterable<TableDataRow>, DataVerifiable {

    private final String fullClassName;

    private final List<TableDataRow> rows = new ArrayList<>();

    private Class<? extends AbstractConf> confClazz;

    private boolean verify = false;

    public TableImportData(String fullClassName) {
        this.fullClassName = fullClassName;
    }

    public void add(TableDataRow row) {
        rows.add(row);
    }

    @Override
    public Iterator<TableDataRow> iterator() {
        return rows.iterator();
    }

    @Override
    public void verify() {
        if (verify) {
            return;
        }
        try {
            confClazz = (Class<? extends AbstractConf>) Class.forName(fullClassName);
        } catch (Exception e) {
            throw new DataVerifyException("fullClassName:" + fullClassName, e);
        }
        verify = true;
    }

    public <C extends AbstractConf> Class<C> getConfClazz() {
        return (Class<C>) confClazz;
    }

    @Override
    public String toString() {
        return "TableImportData{" + "fullClassName='" + fullClassName + '\'' + ", rows=" + rows + ", confClazz=" + confClazz + ", verify=" + verify + '}';
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;

        TableImportData that = (TableImportData) o;
        return fullClassName.equals(that.fullClassName) && rows.equals(that.rows);
    }

    @Override
    public int hashCode() {
        int result = fullClassName.hashCode();
        result = 31 * result + rows.hashCode();
        result = 31 * result + Objects.hashCode(confClazz);
        result = 31 * result + Boolean.hashCode(verify);
        return result;
    }

    public void merge(TableImportData that) {
        if (Objects.equals(this.fullClassName, that.fullClassName)) {
            this.rows.addAll(that.rows);
        }
    }
}